package org.abac4j.context;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.abac4j.annotations.AttributeFunction;
import org.abac4j.util.AnnotationUtil;
import org.abac4j.util.AttributeFunctionUtil;

public class FunctionRepository {
	
	private Map<String, Method> functionMethodMap = new HashMap<String, Method>();
	private Map<String, Class<? extends Object>> functionClassMap = new HashMap<String, Class<? extends Object>>();
	
	public FunctionRepository(Map<String, Set<String>> annotationMap) {
		scanFunctions(annotationMap);	
	}

	private void scanFunctions(Map<String, Set<String>> annotationMap) {
		try{
			Set<String> functionClassesNames = annotationMap.get(AttributeFunction.class.getName());
			
			for(String className : functionClassesNames){
				scanFunctions(Class.forName(className));
			}
		} catch (Exception e){
			throw new RuntimeException(e);
		}
	}

	private void scanFunctions(Class<?> clazz) {
		for(Method method : AnnotationUtil.getMethodsWithAnnotation(clazz, AttributeFunction.class)){
			String name = AttributeFunctionUtil.getFunctionName(method);
			functionMethodMap.put(name, method);
			functionClassMap.put(name, clazz);
		}
	}

	public Map<String, Method> getFunctionMethodMap() {
		return functionMethodMap;
	}

	public void setFunctionMethodMap(Map<String, Method> functionMethodMap) {
		this.functionMethodMap = functionMethodMap;
	}

	public Map<String, Class<? extends Object>> getFunctionClassMap() {
		return functionClassMap;
	}

	public void setFunctionClassMap(
			Map<String, Class<? extends Object>> functionClassMap) {
		this.functionClassMap = functionClassMap;
	}
}